package com.ruoyi.web.controller.statistic.admin;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.ruoyi.common.constant.StatisticEmploymentFileStateConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.vo.ImportProgressVo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.MathUtils;
import com.ruoyi.common.utils.OrikaUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.statistic.domain.StatisticStudentBaseInfo;
import com.ruoyi.statistic.domain.StatisticStudentEmploymentFile;
import com.ruoyi.statistic.domain.StatisticStudentEmploymentInfo;
import com.ruoyi.statistic.domain.vo.*;
import com.ruoyi.statistic.service.IStatisticStudentBaseInfoService;
import com.ruoyi.statistic.service.IStatisticStudentEmploymentFileService;
import com.ruoyi.statistic.service.IStatisticStudentEmploymentInfoService;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.constant.ConfigConstants;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/employment/statistic/fileInfo")
public class StatisticStudentEmploymentFileController extends BaseController {


    @Resource
    private IStatisticStudentBaseInfoService statisticStudentBaseInfoService;

    @Resource
    private IStatisticStudentEmploymentFileService statisticStudentEmploymentFileService;


    @Resource
    private IStatisticStudentEmploymentInfoService statisticStudentEmploymentInfoService;


    /**
     * 配置
     */
    @Resource
    private ISysConfigService configService;


    /**
     * 缓存
     */
    @Resource
    private RedisCache redisCache;

    /**
     * 查询学生就业数据文件管理列表
     */
    @GetMapping("/list")
    public TableDataInfo list(StatisticStudentEmploymentFileSearchVo vo) {
        startPage();
        List<StatisticStudentEmploymentFile> list = statisticStudentEmploymentFileService.selectStatisticStudentEmploymentFileList(vo);
        return getDataTable(list);
    }

    /**
     * 导入excel的档案寄送记录
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/importData")
//    @Log(title = "导入学生就业数据", businessType = BusinessType.IMPORT)
    public AjaxResult importData(@RequestBody StatisticUploadFileVo statisticUploadFileVo) throws Exception {
        //获取上传路径
        String configPath = configService.selectConfigByKey(ConfigConstants.SYS_UPLOAD_DATA_FILE_PATH);
        File file = new File(configPath + statisticUploadFileVo.getFileName());
        ExcelUtil<StatisticStudentEmploymentInfoTemplateVo> util = new ExcelUtil<>(StatisticStudentEmploymentInfoTemplateVo.class);
        InputStream is = Files.newInputStream(file.toPath());
        //将当前excel保存到excel
        List<StatisticStudentEmploymentInfoTemplateVo> recordList = util.importExcel(is);//导入流转list
        //判断下当前就业数据和当前年份是否对应
        boolean result = recordList.stream().anyMatch(x -> !x.getGraduationTime().substring(0, 4).equals(statisticUploadFileVo.getYear()));
        if (result) {
            return error("上传数据和目标年份不匹配");
        }
        List<StatisticStudentEmploymentInfoTemplateResultVo> resultList = new ArrayList<>();
        ImportProgressVo progressVo = new ImportProgressVo();
        if (!recordList.isEmpty()) {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String cur_date_str = df.format(statisticUploadFileVo.getDate());
            Date cur_date = df.parse(cur_date_str);//清除日期的时间部分
            //判断是否有当前日期的文件，如果有，先删除
            StatisticStudentEmploymentFile checkFileModel = statisticStudentEmploymentFileService.selectStatisticStudentEmploymentFileByDate(statisticUploadFileVo.getYear(), cur_date);
            if (ObjectUtil.isNotEmpty(checkFileModel)) {
                File exfile = new File(checkFileModel.getFilePath());
                if (exfile.exists()) {
                    exfile.delete();
                }
                statisticStudentEmploymentFileService.deleteStatisticStudentEmploymentFileByDate(statisticUploadFileVo.getYear(), cur_date);//删除对应记录
            }
            //判断是否有当前日期的数据，如果有，先删除
            if (statisticStudentEmploymentInfoService.checkStatisticStudentEmploymentInfoByDate(statisticUploadFileVo.getYear(), cur_date)) {
                statisticStudentEmploymentInfoService.deleteStatisticStudentEmploymentInfoByDate(statisticUploadFileVo.getYear(), cur_date);
            }
            progressVo.setCountNum(recordList.size());//获取数据总数
            for (StatisticStudentEmploymentInfoTemplateVo vo : recordList) {
                StatisticStudentEmploymentInfoTemplateResultVo resultVo = OrikaUtils.convert(vo, StatisticStudentEmploymentInfoTemplateResultVo.class);
                try {
                    StatisticStudentEmploymentInfo info = OrikaUtils.convert(vo, StatisticStudentEmploymentInfo.class);
                    info.setYear(statisticUploadFileVo.getYear());//设置归属毕业年份
                    info.setAddTime(cur_date);//设置添加时间
                    statisticStudentEmploymentInfoService.insertStatisticStudentEmploymentInfo(info);
                    resultVo.setOpStatus("成功");
                    resultList.add(resultVo);
                    progressVo.addSuccessNum();
                } catch (Exception ex) {
                    //出错
                    resultVo.setOpStatus("失败");
                    resultVo.setMsg(ex.getMessage());
                    resultList.add(resultVo);
                    progressVo.addFailureNum();
                }
                progressVo.addOpNum();
                String test = MathUtils.calcPercent_CEILING(progressVo.getOpNum(), progressVo.getCountNum());
                redisCache.setCacheObject(statisticUploadFileVo.getFileName(), test);
            }
            //添加文件上传数据
            StatisticStudentEmploymentFile fileModel = new StatisticStudentEmploymentFile();
            fileModel.setFileName(statisticUploadFileVo.getFileName());
            fileModel.setFileTime(cur_date);
            fileModel.setStudentCount(recordList.size());
            //获取就业率代码
            String employmentCode = configService.selectConfigByKey(ConfigConstants.EMPLOYMENT_CODE);
            List<String> employmentCodeList = Arrays.asList(employmentCode.split(","));
            Integer employmentCount = recordList.stream().filter(x -> employmentCodeList.contains(x.getGraduationDestinationCode())).collect(Collectors.toList()).size();
            //获取签约率代码
            String signingCode = configService.selectConfigByKey(ConfigConstants.SIGNING_CODE);
            List<String> signingCodeList = Arrays.asList(signingCode.split(","));
            Integer signingCount = recordList.stream().filter(x -> signingCodeList.contains(x.getGraduationDestinationCode())).collect(Collectors.toList()).size();
            fileModel.setFileYear(statisticUploadFileVo.getYear());//设置归属毕业年份
            fileModel.setSigningCount(signingCount);
            fileModel.setSigningRate(MathUtils.calcPercent(signingCount, recordList.size()));
            fileModel.setEmploymentCount(employmentCount);
            fileModel.setEmploymentRate(MathUtils.calcPercent(employmentCount, recordList.size()));
            fileModel.setFilePath(file.getPath());
            fileModel.setFileState(StatisticEmploymentFileStateConstants.Local);
            statisticStudentEmploymentFileService.insertStatisticStudentEmploymentFile(fileModel);
        }
        String fileExt = file.getName().substring(file.getName().lastIndexOf("."), file.getName().length());
        String newName = UUID.fastUUID().toString().replace("-", "");//随机生成uuid文件名
        String configResultPath = configService.selectConfigByKey(ConfigConstants.SYS_UPLOAD_RESULT_FILE_PATH);
        String resultFileName = configResultPath + newName + fileExt;
        EasyExcel.write(resultFileName, StudentInfoTemplateResultVo.class).sheet("sheet1").registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).doWrite(resultList);
        progressVo.setResultFileName(newName + fileExt);
        redisCache.setCacheObject(statisticUploadFileVo.getFileName(), "100");
        //TODO 导入完成后，需要删除数据 或者 定时删除数据
        return success(progressVo);
    }


    /**
     * 上传学生就业数据文件
     *
     * @param file
     * @return
     * @throws Exception
     */
//    @Log(title = "上传学生就业数据文件", businessType = BusinessType.UPLOAD)
//    @PreAuthorize("@ss.hasPermi('student:employment:file:upload')")
    @PostMapping("/uploadData")
    public AjaxResult uploadDataFile(MultipartFile file) throws IOException {
        String fileExt = FileUploadUtils.getExtension(file);//文件后缀名
        String newName = UUID.fastUUID().toString().replace("-", "");//随机生成uuid文件名
        String configPath = configService.selectConfigByKey(ConfigConstants.SYS_UPLOAD_DATA_FILE_PATH);
        String savePath = configPath + newName + "." + fileExt;
        File newFile = new File(savePath);
        file.transferTo(newFile);
        return success(newName + "." + fileExt);
    }

    /**
     * 获取当前文件的导出进度
     *
     * @return
     */
    @GetMapping("/importDataProgress/{fileName}")
    public AjaxResult importDataProgress(@PathVariable("fileName") String fileName) {
        if (StringUtils.isEmpty(fileName)) {
            return success(0);
        }
        String percent = redisCache.getCacheObject(fileName);
        if (StringUtils.isEmpty(percent)) {
            return success(0);
        }
        return success(percent);
    }


    /**
     * 删除学生就业数据文件管理
     */
    @DeleteMapping("/{id}")
    public AjaxResult remove(@PathVariable Long id) {
        StatisticStudentEmploymentFile fileModel = statisticStudentEmploymentFileService.selectStatisticStudentEmploymentFileById(id);
        //判断当前文件目前位置
        if (fileModel.getFileState().equals(StatisticEmploymentFileStateConstants.Local)) {
            File file = new File(fileModel.getFilePath());
            if (file.exists()) {
                file.delete();//删除文件
            }
        } else if (fileModel.getFileState().equals(StatisticEmploymentFileStateConstants.Cloud)) {

        } else {

        }
        //判断是否还存在当天的数据
        if (statisticStudentEmploymentInfoService.checkStatisticStudentEmploymentInfoByDate(fileModel.getFileYear(), fileModel.getFileTime())) {
            //删除当天存在的数据
            statisticStudentEmploymentInfoService.deleteStatisticStudentEmploymentInfoByDate(fileModel.getFileYear(), fileModel.getFileTime());
        }
        //判断下临时计算表是否还存在当天的数据
        //TODO 这边暂时不导入临时表
//        Date currentYearMaxDate = studentEmploymentInfoTemporaryService.selectMaxDateByYear(fileModel.getFileYear());
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//        if (sdf.format(currentYearMaxDate).equals(sdf.format(fileModel.getFileTime()))) {
//            //如果当前年月日的数据存在于临时表，
//            //那么先删除临时表的数据，
//            studentEmploymentInfoTemporaryService.deleteStudentEmploymentInfoTemporaryByDate(fileModel.getFileYear(), currentYearMaxDate);
//            //用上一天最大的数据来填充
//            Date fileMaxYearDate = statisticStudentEmploymentFileService.selectMaxDateByYear(fileModel.getFileYear());//获取指定的年份中，最后一天的数据
//            studentEmploymentInfoTemporaryService.synDateFormStudentEmploymentInfo(fileModel.getFileYear(), fileMaxYearDate);//同步指定日期到临时表
//        }
        return toAjax(statisticStudentEmploymentFileService.deleteStatisticStudentEmploymentFileById(id));
    }


    /**
     * 下载学生信息导入模板文件
     *
     * @param response
     */
    @PreAuthorize("@ss.hasPermi('system:employment:file:download')")
    @PostMapping("/download/{id}")
    public void download(@PathVariable Long id, HttpServletResponse response) throws Exception {
        //TODO 1.如果文件不存在怎么办 2.文件可能存在云端
        StatisticStudentEmploymentFile fileModel = statisticStudentEmploymentFileService.selectStatisticStudentEmploymentFileById(id);
        File file = new File(fileModel.getFilePath());
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
        FileUtils.setAttachmentResponseHeader(response, file.getName());
        FileUtils.writeBytes(file.getPath(), response.getOutputStream());
    }


    /**
     * 比对就业信息文件和本地学生数据的差额
     *
     * @param id
     * @param response
     * @throws Exception
     */
    @PostMapping(value = "/contrast/{id}")
    public void contrast(@PathVariable Long id, HttpServletResponse response) throws Exception {
        StatisticStudentEmploymentFile fileModel = statisticStudentEmploymentFileService.selectStatisticStudentEmploymentFileById(id);
        List<ContrastResultVo> resultList = new ArrayList<>();
        //获取对应文件数据
        List<StatisticStudentEmploymentInfo> query = statisticStudentEmploymentInfoService.selectStatisticStudentEmploymentInfoByDate(fileModel.getFileTime());
        for (StatisticStudentEmploymentInfo item : query) {
            ContrastResultVo resultVo = new ContrastResultVo();
            StatisticStudentBaseInfo baseModel = statisticStudentBaseInfoService.selectStatisticStudentBaseInfoByCode(item.getCode());
            resultVo.setCode(item.getCode());
            resultVo.setName(item.getName());
            if (baseModel != null) {
                resultVo.setDepartment(baseModel.getDepartment());
                resultVo.setMajor(baseModel.getMajor());
                resultVo.setState("匹配");
//                resultVo.setRemark("未找到该学生对应的基础信息！");
            } else {
                resultVo.setState("未匹配");
                resultVo.setRemark("未找到该学生对应的基础信息！");
            }
            resultList.add(resultVo);
        }
        String fileExt = ".xlsx";
        String newName = UUID.fastUUID().toString().replace("-", "");//随机生成uuid文件名
        String configResultPath = configService.selectConfigByKey(ConfigConstants.SYS_UPLOAD_RESULT_FILE_PATH);
        String resultFileName = configResultPath + newName + fileExt;
        EasyExcel.write(resultFileName, ContrastResultVo.class).sheet("sheet1").registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).doWrite(resultList);
        File file = new File(resultFileName);
        if (file.exists()) {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
            FileUtils.setAttachmentResponseHeader(response, file.getName());
            FileUtils.writeBytes(file.getPath(), response.getOutputStream());
        }
    }

}
